package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONUtil;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.dubbo.api.*;
import com.tanhua.dubbo.enums.HuanXinMessageType;
import com.tanhua.dubbo.pojo.Question;
import com.tanhua.dubbo.pojo.RecommendUser;
import com.tanhua.dubbo.pojo.UserInfo;
import com.tanhua.dubbo.vo.PageInfo;
import com.tanhua.dubbo.vo.UserLocationVo;
import com.tanhua.server.config.DefaultConfig;
import com.tanhua.server.vo.NearUserVo;
import com.tanhua.server.vo.TodayBest;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class TanHuaService {

    @DubboReference(version = "1.0.0")
    private UserInfoApi userInfoApi;

    @DubboReference(version = "1.0.0")
    private RecommendUserApi recommendUserApi;

    @DubboReference(version = "1.0.0")
    private QuestionApi questionApi;

    @DubboReference(version = "1.0.0")
    private HuanXinApi huanXinApi;

    @DubboReference(version = "1.0.0")
    private VisitorsApi visitorsApi;

    @DubboReference(version = "1.0.0")
    private UserLocationApi userLocationApi;

    @DubboReference(version = "1.0.0")
    private UserLikeApi userLikeApi;

    @Autowired
    private IMService imService;

    @Autowired
    private DefaultConfig defaultConfig;

    public Object queryUserInfo(Long userId) {
        UserInfo userInfo = this.userInfoApi.queryByUserId(userId);
        if (null == userInfo) {
            return ErrorResult.builder().errCode("404")
                    .errMessage("此用户信息不存在！").build();
        }
        TodayBest todayBest = BeanUtil.toBeanIgnoreError(userInfo, TodayBest.class);
        todayBest.setFateValue(Convert.toLong(this.recommendUserApi.queryScore(userId, UserThreadLocal.get()), 80L));
        todayBest.setGender(userInfo.getSex().name().toLowerCase());

        //记录访客信息
        this.visitorsApi.saveVisitor(userId, UserThreadLocal.get(), "个人主页");

        return todayBest;
    }

    public String queryQuestion(Long userId) {
       List<Question>  questionList = this.questionApi.queryQuestion(userId);
       if(questionList.size()>1){
           return questionList.get(0).getTxt();
       }
        if (questionList.size()>0) {
            Question question = questionList.get(0);
            return question.getTxt();
        }
        return "你是GG还是MM？";//默认问题
    }

    /**
     * 回复陌生人问题
     *
     * @param userId 好友id
     * @param reply
     * @return
     */
    public Object replyQuestion(Long userId, String reply) {
        //封装消息的json数据
        //{"userId":1,"huanXinId":"HX_1","nickname":"黑马小妹","strangerQuestion":"问题","reply":"回复"}
        Long myUserId = UserThreadLocal.get();
        UserInfo userInfo = this.userInfoApi.queryByUserId(myUserId);

        //构建消息
        Map<Object, Object> msgMap = MapUtil.builder()
                .put("userId", myUserId)
                .put("huanXinId", "HX_" + myUserId)
                .put("nickname", userInfo.getNickName())
                .put("strangerQuestion", this.queryQuestion(userId))
                .put("reply", reply).build();

        //json格式的消息
        String msgJson = JSONUtil.toJsonStr(msgMap);

        //调用dubbo服务发送消息给对方
        Boolean result = this.huanXinApi
                .sendMsgFromAdmin("HX_" + userId, HuanXinMessageType.TXT, msgJson);

        if (result) {
            return null;
        }
        return ErrorResult.builder()
                .errCode("500").errMessage("回复陌生人问题出错，请稍后再试！").build();
    }

    /**
     * 搜附近
     *
     * @param gender
     * @param distance
     * @return
     */
    public List<NearUserVo> queryNearUser(String gender, String distance) {
        //查询自己的位置
        Long userId = UserThreadLocal.get();
        UserLocationVo userLocationVo = this.userLocationApi.queryByUserId(userId);
        if (null == userLocationVo) {

            return Collections.emptyList();
        }

        //根据自己的位置查询附近的人
        PageInfo<UserLocationVo> pageInfo = this.userLocationApi.queryUserFromLocation(userId, userLocationVo.getLongitude(),
                userLocationVo.getLatitude(), Convert.toDouble(distance), 1, 20);
        List<UserLocationVo> records = pageInfo.getRecords();
        if (CollUtil.isEmpty(records)) {
            return Collections.emptyList();
        }

        //查询用户列表
        Map<Long, UserInfo> userInfoMap = this.userInfoApi.queryMapByUserIdList(CollUtil.getFieldValues(records, "userId"));

        //排除不是异性的用户
        UserInfo userInfo = this.userInfoApi.queryByUserId(userId);
        if(userInfo.getSex().getValue() == 1){
            for (Object id:CollUtil.getFieldValues(records, "userId")) {
                if(userInfoMap.get(id).getSex().getValue() != 2){
                    userInfoMap.remove(id);
                }
            }
        }else if(userInfo.getSex().getValue() == 2){
            for (Object id:CollUtil.getFieldValues(records, "userId")) {
                if(userInfoMap.get(id).getSex().getValue() != 1){
                    userInfoMap.remove(id);
                }
            }
        }

        return records.stream().map(vo ->
                BeanUtil.toBeanIgnoreError(userInfoMap.get(vo.getUserId()), NearUserVo.class)
        ).collect(Collectors.toList());
    }

    /**
     * 查询推荐卡片列表，从推荐列表中随机选取20个用户
     *
     * @return
     */
    public List<TodayBest> queryCardsList() {
        //通过dubbo服务查询推荐的用户列表，其中要排除已喜欢和已不喜欢的用户
        Long userId = UserThreadLocal.get();
        //查询推荐列表
        List<RecommendUser> recommendUserList = this.recommendUserApi.queryCardList(userId, 50);
        if (CollUtil.isEmpty(recommendUserList)) {
            List<Long> idList = Arrays.asList(this.defaultConfig.getIdList());
            recommendUserList = this.recommendUserApi.queryCardListDefault(userId,idList);
        }

        //随机从中选取20个用户返回
        //实现方案有2种：
        //方案一：遍历列表，随机生成下标，从集合中获取数据 ，该方案的问题：可能会重复，解决重复问题就得进行递归
        //方案二：将集合打乱顺序，截取前20个数据即可

        Collections.shuffle(recommendUserList); //打乱顺序

        List<RecommendUser> result = ListUtil.sub(recommendUserList, 0, 20);

        //查询用户信息
        Map<Long, UserInfo> userInfoMap = this.userInfoApi.queryMapByUserIdList(CollUtil.getFieldValues(result, "userId"));

        return result.stream().map(recommendUser -> {
            UserInfo userInfo = userInfoMap.get(recommendUser.getUserId());
            TodayBest todayBest = BeanUtil.toBeanIgnoreError(userInfo, TodayBest.class);
            todayBest.setFateValue(recommendUser.getScore().longValue()); //缘分值
            todayBest.setGender(userInfo.getSex().name().toLowerCase()); //性别
            return todayBest;
        }).collect(Collectors.toList());

    }

    public void likeUser(Long likeUserId) {
        Long userId = UserThreadLocal.get();
        this.userLikeApi.likeUser(userId, likeUserId);

        //如果用户相互喜欢，添加成好友
        if (this.userLikeApi.isMutualLike(userId, likeUserId)) {
            this.imService.addContacts(likeUserId);
        }
    }

    public void notLikeUser(Long likeUserId) {
        this.userLikeApi.notLikeUser(UserThreadLocal.get(), likeUserId);
    }
}
